/**
 * Copyright © 2021 郑心怡. All rights reserved.
 *
 * @Title: UserInfoController.java
 * @Prject: com.interesting.examsystem.user.controller
 * @Package: com.interesting.examsystem.user.controller
 * @author: ZhengXinyi
 * @date: 2021-07-24
 * @version: V1.0
 */
package com.interesting.examsystem.user.controller;

import java.util.*;

import cn.hutool.core.util.ObjectUtil;
import com.interesting.examsystem.common.constant.CommonConstant;
import com.interesting.examsystem.common.exception.PasswordErrorException;
import com.interesting.examsystem.common.exception.TheUserHasNoException;
import com.interesting.examsystem.common.utils.EncryptUtil;
import com.interesting.examsystem.role.model.RoleVO;
import com.interesting.examsystem.user.model.User;
import com.interesting.examsystem.user.service.IUserRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.interesting.examsystem.common.annotation.LogAnnotation;
import com.interesting.examsystem.common.constant.RestConstant;
import com.interesting.examsystem.common.core.controller.BaseController;
import com.interesting.examsystem.common.enums.OperateTypeEnum;
import com.interesting.examsystem.common.response.Result;
import com.interesting.examsystem.common.response.ResultGenerator;
import com.interesting.examsystem.user.model.UserInfoDTO;
import com.interesting.examsystem.user.model.UserInfoVO;
import com.interesting.examsystem.user.service.IUserInfoService;
import com.interesting.examsystem.common.utils.InputInjectFilter;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName: UserLoginController
 * @Description: 控制层
 * @author: ZhengXinyi
 * @date: 2021-07-24
 */
@RestController
@RequestMapping(UserLoginController.PATH)
@Api(tags = "系统->用户")
public class UserLoginController extends BaseController {
    public final static String PATH = RestConstant.VERSION_V1 + "/sys/user/login";
    // 日志审计列表中“菜单路径”
    private static final String MENU_NAME = "系统->用户";
    // 日志审计列表中“日志内容”显示信息
    private static final String CONTENT = "用户登录管理";
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IUserRoleService userRoleService;


    /**
     * @param user
     * @return
     * @Title: selectPage
     * @Description: 用户登录
     */
    @LogAnnotation(menuName = MENU_NAME, content = CONTENT, operateType = OperateTypeEnum.QUERY)
    @PostMapping
    @ApiOperation(value = "用户登录", httpMethod = "POST")
    @ApiImplicitParam(name = "user", value = "登录参数", required = true)
    public Result login(@RequestBody @Validated User user, HttpServletRequest request) {
        user = (User) InputInjectFilter.encodeInputString(user, UserInfoDTO.class);
        //更新用户表上次登录时间、更新人、更新时间等字段
        UserInfoVO userInfoVO = userInfoService.selectByName(user.getUsername());

        try {
            if (ObjectUtil.isNotEmpty(userInfoVO)) throw new TheUserHasNoException("用户不存在");

            if (!userInfoVO.getPassword().equals(EncryptUtil.encrypt(user.getPassword())))
                throw new PasswordErrorException("密码错误");

        } catch (TheUserHasNoException e) {
            return ResultGenerator.genUnauthorizedResult(e.getMessage());
        } catch (PasswordErrorException e) {
            return ResultGenerator.genUnauthorizedResult(e.getMessage());
        }

        UserInfoVO updateUser = new UserInfoVO();
        updateUser.setId(userInfoVO.getId());
        updateUser.setLastLoginTime(new Date());
        updateUser.setUpdateTime(new Date());
        updateUser.setOperatorId(super.getOperatorId());
        userInfoService.update(updateUser);

        //获取该用户所拥有的权限
        List<RoleVO> roleVOS = userRoleService.selectListByUser(userInfoVO.getId());
        List<String> roles = new ArrayList<>();
        roleVOS.forEach(roleVO -> {
            roles.add(roleVO.getRoleName());
        });

        //此处还可以进行一些处理，比如登录成功之后可能需要返回给前台当前用户有哪些菜单权限，
        //进而前台动态的控制菜单的显示等，具体根据自己的业务需求进行扩展
        userInfoVO.setRoles(roles);

        //存储用户信息
        request.getSession().setAttribute(CommonConstant.SESSION_USER, userInfoVO);
        return ResultGenerator.genOkResult(userInfoVO);
    }

    /**
     * 用户退出登录
     *
     * @param request
     * @return
     */
    @LogAnnotation(menuName = MENU_NAME, content = CONTENT, operateType = OperateTypeEnum.QUERY)
    @GetMapping("/out")
    @ApiOperation(value = "用户退出登录", httpMethod = "GET")
    public Result loginOut(HttpServletRequest request) {
        //删除用户信息
        request.getSession().removeAttribute(CommonConstant.SESSION_USER);
        return ResultGenerator.genOkResult();
    }

}
